package compute;

import util.MyBitSet;
import data.DataBloc;
import data.Key;

public class TDEA implements BlocEncrypter {

	DES des1;
	DES des2;
	DES des3;

	/**
	 * constructeur de TDEA
	 * 
	 * @param k1
	 * @param k2
	 * @param k3
	 */
	public TDEA(Key k1, Key k2, Key k3) {
		des1 = new DES(k1);
		des1 = new DES(k2);
		des1 = new DES(k3);
	}

	/**
	 * construction d'un crypteur selon une option de clef: keyingOption1 => k1
	 * != k2 != k3 keyingOption2 => k1 != k2 ; k3 != k2 ; k1 = k3 keyingOption1
	 * => k1 = k2 = k3
	 * 
	 * @param k
	 */
	public TDEA(KeyingOption k) {
		Key k1, k2, k3;
		switch (k) {
		case KeyingOption1:
			k1 = new Key();
			do {
				k2 = new Key();
			} while (k1.getValue().equals(k2.getValue()));
			do {
				k3 = new Key();
			} while (k3.getValue().equals(k1.getValue())
					|| k3.getValue().equals(k2.getValue()));
			break;

		case KeyingOption2:
			k1 = new Key();
			do {
				k2 = new Key();
			} while (k1.getValue().equals(k2.getValue()));
			k3 = k1.clone();
			break;

		case KeyingOption3:
			k1 = new Key();
			k2 = k1.clone();
			k3 = k1.clone();
			break;
		// par défaut l'option 1
		default:
			k1 = new Key();
			do {
				k2 = new Key();
			} while (k1.getValue().equals(k2.getValue()));
			do {
				k3 = new Key();
			} while (k3.getValue().equals(k1.getValue())
					|| k3.getValue().equals(k2.getValue()));
			break;
		}
		des1 = new DES(k1);
		des2 = new DES(k2);
		des3 = new DES(k3);
	}

	/**
	 * retourne la clef n°i (il y a 3 clefs k1, k2, k3)
	 * 
	 * @param i
	 *            l'index de la clef
	 * @return
	 */
	public Key getKey(int i) {
		switch (i) {
		case 1:
			return des1.getKey();
		case 2:
			return des2.getKey();
		case 3:
			return des3.getKey();
		default:
			return null;
		}
	}

	public void setKey(int i, Key k) {
		switch (i) {
		case 1:
			des1.setKey(k);
			break;
		case 2:
			des2.setKey(k);
			break;
		case 3:
			des3.setKey(k);
			break;
		}
	}

	/**
	 * chiffrement de DataBloc
	 */
	@Override
	public DataBloc encrypt(DataBloc plainText) {
		return des3.encrypt(des2.decrypt(des1.encrypt(plainText)));
	}

	/**
	 * déchiffrement de DataBloc
	 */
	@Override
	public DataBloc decrypt(DataBloc cypherText) {
		return des1.decrypt(des2.encrypt(des3.decrypt(cypherText)));
	}

	public static void main(String[] args) {
		TDEA tdea = new TDEA(KeyingOption.KeyingOption1);

		MyBitSet donnee = new MyBitSet("0101 0101" + "0101 0101" + "0101 0101"
				+ "0101 0101" + "0101 0101" + "0101 0101" + "0101 0101"
				+ "0101 0101");
		DataBloc d = new DataBloc(donnee);
		DataBloc r = tdea.encrypt(d);
		System.out.println(r.getValue().print());

		r = tdea.decrypt(r);
		System.out.println(r.getValue().print());
		r.getValue().flip(0, 64);
		System.out.println(!d.getValue().intersects(r.getValue()));

	}

}
